package com.doeis.minaserver;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.doeis.log.QueueManager;
import com.doeis.minaserver.container.BasicModule;
import com.doeis.minaserver.dao.UserDao;
import com.doeis.minaserver.module.ClientConnectionManager;
import com.doeis.minaserver.module.InfoPacketRouter;
import com.doeis.minaserver.module.PacketRouter;
import com.doeis.minaserver.module.SocketAcceptorManager;
import com.doeis.minaserver.module.UserManager;
import com.doeis.push.BaiduServiceContext;
import com.doeis.uwork.dao.GroupMsgMongoDao;
import com.doeis.uwork.dao.HnMsgAuthorityDao;
import com.doeis.uwork.dao.HnMsgAuthorityPeopleDao;
import com.doeis.uwork.dao.ItemDao;
import com.doeis.uwork.dao.ItemNotesDao;
import com.doeis.uwork.dao.MessageDao;
import com.doeis.uwork.dao.MinaSessionLogMongoDao;
import com.doeis.uwork.dao.OffPacketMongoDao;
import com.doeis.uwork.dao.PrivateMsgMongo;
import com.doeis.uwork.dao.ShareDao;
import com.doeis.uwork.dao.TemplateDao;
import com.doeis.uwork.entity.mongo.PictureInfoMongo;
import com.doeis.uwork.module.GroupMsgPacketRouter;
import com.doeis.uwork.module.MessagePacketRouter;
import com.doeis.uwork.module.PrivateMsgPacketRouter;
import com.doeis.uwork.module.RollPolingModule;
import com.doeis.uwork.module.SystemPacketRouter;
import com.doeis.uwork.servce.GroupMsgService;
import com.doeis.uwork.servce.MessageService;
import com.doeis.uwork.servce.PrivateMsgService;
import com.google.inject.Guice;
import com.google.inject.Injector;


public class NettyServer {
	private static Logger log = Logger.getLogger(NettyServer.class);
	private static NettyServer instance; // 服务器实例
	private static boolean isRunning = false;
	private ClassLoader loader; // 模块加载器
	
	private  Injector injector = Guice.createInjector();
	
	// 模块存储器
	private Map<Class, BasicModule> modules = new LinkedHashMap<Class, BasicModule>();
	
	private NettyServer() {
	}
	
	
	public synchronized static NettyServer getInstance() {
		if(instance == null)
			instance = new NettyServer();
		return instance;
	}
	
	/**
	 * 启动服务器
	 */
	public synchronized void start() {
		
		if (isRunning){
			throw new IllegalStateException("A server is already running");
		}
		
		// 初始化服务器
		initialize();
		
		// 加载、初始化、启用功能模块
		loadModules();
		initModules();
		startModules();
		
		//加载百度推送
		BaiduServiceContext.initPushBaidu();
		isRunning = true;
		
	}
	
	/**
	 * 服务器初始化
	 */
	private void initialize() {
		loader = Thread.currentThread().getContextClassLoader();
	}
	
	/**
	 * 加载所有功能模块
	 */
	private void loadModules(){
		
		//加载数据源管理
//		loadModule(DataSourceManager.class);
//		loadModule(ActiveMqQueue.class);
		
		//加载包处理模块
		loadModule(PacketRouter.class);
		loadModule(InfoPacketRouter.class);
		loadModule(MessagePacketRouter.class);
		loadModule(GroupMsgPacketRouter.class);
		loadModule(PrivateMsgPacketRouter.class);
		loadModule(SystemPacketRouter.class);
		
		loadModule(UserManager.class);
		loadModule(MessageService.class);
		loadModule(GroupMsgService.class);
		loadModule(PrivateMsgService.class);
		loadModule(RollPolingModule.class);
		
		//日志队列开启
		loadModule(QueueManager.class);
		
		//最后加载网络模块，启动服务
		loadModule(ClientConnectionManager.class);
		loadModule(SocketAcceptorManager.class);
		
	}
	
	/**
	 * 加载所有模块
	 * @param module
	 */
	private void loadModule(Class module) {
		try {
			Class modClass = loader.loadClass(module.getName());
			BasicModule mod = (BasicModule) modClass.newInstance();
			this.modules.put(module, mod);
		} catch (Exception e) {
			log.error("loadModule error,caused by:" + e.getMessage(), e);
		}
	}

	/**
	 * 对加载的模块进行初始化
	 */
	private void initModules() {
		for (BasicModule module : modules.values()) {
			boolean isInitialized = false;
			try {
				module.initialize(this);
				isInitialized = true;
			} catch (Exception e) {				
				// Remove the failed initialized module
				this.modules.remove(module.getClass().getName());
				if (isInitialized) {
					module.stop();
				}
				log.debug("initModule error,caused by:" + e.getMessage(), e);
			}
		}
	}

	/**
	 * 启用模块已经加载的模块
	 */
	private void startModules() {
		for (BasicModule module : modules.values()) {
			boolean started = false;
			try {
				module.start();
				started = true;
			} catch (Exception e) {
				if (started && module != null) {
					module.stop();
				}
				log.error("startModule error,caused by:"+e.getMessage(), e);
			}
		}
	}
	
	/**
	 * 关闭已经启动的模块
	 */
	private void stopModules() {
		//这里需要注意最后一个关闭日志管理
		BasicModule queueModule = modules.get(QueueManager.class);
		if(queueModule!=null){
			modules.remove(QueueManager.class);
		}
		
		BasicModule connectionManager = modules.get(ClientConnectionManager.class);
		if(connectionManager!=null){
			modules.remove(ClientConnectionManager.class);
		}
		
		if(queueModule!=null){
			modules.put(QueueManager.class, queueModule);
		}
		
		if(connectionManager!=null){
			modules.put(ClientConnectionManager.class, connectionManager);
		}
		
		
		for(BasicModule module : modules.values()){
			System.err.println(module.getName());
			try{
				module.stop();
			}catch (Exception e) {
				log.error("stopModule error,caused by:"+e.getMessage(), e);
			}
		}
		
	}
	
	/**
	 * 关闭服务器
	 */
	public synchronized void stop() {
		stopModules();
		modules.clear();
		isRunning = false;
		log.error("服务器停止结束************");
		System.exit(0);
	}
	
	public PacketRouter getPacketRouter(){
		return (PacketRouter)modules.get(PacketRouter.class);
	}
	
	public <T>T  getT(Class<T> c){
		return (T)modules.get(c);
	}
	
	public MessagePacketRouter getMessagePacketRouter(){
		return (MessagePacketRouter)modules.get(MessagePacketRouter.class);
	}
	
	public UserManager getUserManager(){
		return (UserManager)modules.get(UserManager.class);
	}
	
	public InfoPacketRouter getInfoPacketRouter(){
		return (InfoPacketRouter)modules.get(InfoPacketRouter.class);
	}
	public GroupMsgPacketRouter getGroupMsgPacketRouter(){
		return (GroupMsgPacketRouter)modules.get(GroupMsgPacketRouter.class);
	}
	public PrivateMsgPacketRouter getPrivateMsgPacketRouter(){
		return (PrivateMsgPacketRouter)modules.get(PrivateMsgPacketRouter.class);
	}
	
	public ClientConnectionManager getClientConnectionManager(){
		return (ClientConnectionManager)modules.get(ClientConnectionManager.class);
	}
	
	//反射类对象
	public <T>T  getInjectorInstance(Class<T> c){
		return injector.getInstance(c);
	}
	
	
	//dao 层数据接口
	
	public UserDao  getUserDao(){
		return injector.getInstance(UserDao.class);
	}
	public ItemDao  getItemDao(){
		return injector.getInstance(ItemDao.class);
	}
	
	public ShareDao  getShareDao(){
		return injector.getInstance(ShareDao.class);
	}
	
	public ItemNotesDao  getItemNotesDao(){
		return injector.getInstance(ItemNotesDao.class);
	}
	
	public TemplateDao  getTemplateDao(){
		return injector.getInstance(TemplateDao.class);
	}
	
	public HnMsgAuthorityDao  getHnMsgAuthorityDao(){
		return injector.getInstance(HnMsgAuthorityDao.class);
	}
	
	public HnMsgAuthorityPeopleDao  getHnMsgAuthorityPeopleDao(){
		return injector.getInstance(HnMsgAuthorityPeopleDao.class);
	}
	
	//mongo 接口
	public OffPacketMongoDao  getOffPacketMongoDao(){
		return injector.getInstance(OffPacketMongoDao.class);
	}
	
	public MessageDao  getMessageDao(){
		return injector.getInstance(MessageDao.class);
	}
	
	public PrivateMsgMongo  getPrivateMsgMongo(){
		return injector.getInstance(PrivateMsgMongo.class);
	}
	
	public MinaSessionLogMongoDao getMinaSessionLogMongoDao(){
		return injector.getInstance(MinaSessionLogMongoDao.class);
	}
	
	public PictureInfoMongo  getPictureInfoMongo(){
		return injector.getInstance(PictureInfoMongo.class);
	}
	
	public GroupMsgMongoDao  getGroupMsgMongoDao(){
		return injector.getInstance(GroupMsgMongoDao.class);
	}
	
}
